<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <link rel="shortcut icon" type="image/x-icon" href="../favicon.ico"/>
    <title>如何自定义 Tag jetbrick-template</title>

    <link href="../assets/css/application.min.css" rel="stylesheet" type="text/css"/>

    <!--[if lt IE 9]><script src="../assets/js/html5shiv.js"></script><![endif]-->
    <script type="text/javascript" src="../assets/js/application.min.js"></script>
</head>

<body>
<a href="https://github.com/subchen/jetbrick-template/" target="_blank">
    <img src="../assets/images/forkme_right_orange.png" alt="Fork me on GitHub" class="fork-me-on-github">
</a>

<div class="jb-topbar">
    <div class="container">
        <a href="http://subchen.github.io/"><img src="../assets/images/logo-mini.png"/></a>
        <!--
        <ul class="menubar">
            <li><a href="">commons</a></li>
            <li><a href="">webmvc</a></li>
            <li><a href="">template</a></li>
            <li><a href="">orm</a></li>
            <li><a href="">widget</a></li>
            <li><a href="">javadoc-chm</a></li>
        </ul>
        -->
        <div class="pull-right" style="color:#fff;line-height:40px;font-size:16px;padding-right:20px">QQ 交流圈：310491655</div>
    </div>
</div>

<div class="jb-banner">
    <div class="container">
        <a href="http://subchen.github.io/jetbrick-template/index.html">
            <img src="../assets/images/jetbrick-template-logo.png" class="pull-left" />
        </a>
        <ul class="description">
            <li>1. 全新一代 Java 模板引擎</li>
            <li>2. 具有高性能、高扩展性</li>
            <li>3. 完美替代 JSP, Velocity 等引擎模板</li>
        </ul>
        <a href="download/jetbrick-template-1.2.3.zip" class="download-button">
            <img src="../assets/images/download.png"/>
            <span>jetbrick-template-1.2.3.zip<br/>2014-03-10</span>
        </a>
    </div>
</div>

<div class="container">
    <div class="jb-section">
        <ul class="tabs">
            <li><a href="overview.html">简介</a></li>
            <li><a href="download.html">下载</a></li>
            <li><a href="userguide.html">开发指南</a></li>
            <li><a href="config.html">配置指南</a></li>
            <li><a href="syntax.html">语法指南</a></li>
            <li><a href="integrate.html">Web 框架集成</a></li>
            <!--
            <li><a href="example.html">例子</a></li>
            -->
            <li><a href="faq.html" class="selected">FAQ</a></li>
            <li><a href="about.html">关于</a></li>
        </ul>
    </div>
</div>

<div class="container">
    <div class="announcement">
        <a href="download.html#version">2014-03-10：jetbrick-template-1.2.3 正式版已发布，欢迎下载。</a>
    </div>
</div>

<div class="container">


    <div class="markdown">

<!-- markdown body begin -->
	<ul> 
 <li><a href="faq-compile.html">jetbrick-template 将模板编译成 Java Class 有什么好处？</a></li> 
 <li><a href="faq-define.html">jetbrick-template 中为什么需要 #define 声明变量类型？</a></li> 
 <li><a href="faq-error.html">jetbrick-template 常见错误分析</a></li> 
 <li><a href="faq-autoscan.html">jetbrick-template 如何让自动扫描发现用户自定义的扩展方法/函数/标签 Class</a></li> 
 <li><a href="faq-include.html">jetbrick-template 中如何嵌入子模板？（父子间参数传递）</a></li> 
 <li><a href="faq-tag.html">jetbrick-template 中如何自定义 Tag？</a></li> 
 <li><a href="faq-layout.html">jetbrick-template 中如何实现 layout 功能？</a></li> 
 <li><a href="faq-spring.html">jetbrick-template 在 Spring 中的集成方法</a></li> 
</ul>

    <h1><a name="x223019712"></a><span>1 如何自定义 Tag</span></h1>
<p>jetbrick-template 支持自定义 Tag，类似于 JSP Taglib，但是要比 JSP Taglib 更简单更好用。</p>
<p>这里以建立一个支持 Cache 的 Tag 为例。</p>
<h2><a name="x807110256"></a><span>1.1 Cache Tag 代码范例：</span></h2>
<h3><a name="x2047045847"></a><span>1.1.1 首先定义一个 Tag 实现方法</span></h3>
<p>每一个自定义的 Tag 对应一个 Java 的 <code>public</code> <code>static</code> 的方法。比如我们这里定义的 cache tag，如下:</p>
<p>Tag 方法定义：</p> 
<script type="syntaxhighlighter" class="brush: java"><![CDATA[
public class MyTags {
    public static void cache(JetTagContext ctx, String name, int timeout) throws IOException {
        Cache cache = CacheManager.getCache(); // 请用自己的 Cache 代替
        Object value = cache.get(name);
        if (value == null) {
            value = ctx.getBodyContext();
            cache.put(name, value, timeout);
        }
        ctx.getWriter().print(value);
    }
}
]]></script>
<h3><a name="x1610375963"></a><span>1.1.2 必须要注册到全局的 JetEngine 中，我们使用如下的配置：</span></h3> 
<script type="syntaxhighlighter" class="brush: text"><![CDATA[
import.tags = MyTags, ...
]]></script>
<h3><a name="x289378703"></a><span>1.1.3 然后写对应的例子模板：</span></h3> 
<script type="syntaxhighlighter" class="brush: text"><![CDATA[
#tag cache("sum", 10)
    计算结果将被缓存10秒： ${1+2+3+4+5+6+7+8+9}
#end
]]></script>
<h2><a name="x718697860"></a><span>1.2 Cache Tag 代码说明</span></h2>
<p>对于每一个 Tag 的方法声明，有如下要求：</p> 
<ul> 
 <li>方法签名必须是 <code>public</code> <code>static</code></li> 
 <li>方法返回值必须是 <code>void</code></li> 
 <li>方法第一个参数必须是 <code>JetTagContext</code>， 其余参数自定义</li> 
 <li>允许 throws 任意的 Throwable</li> 
 <li>允许定义相同名字的 Tag，但是方法参数不一样 （Overload）</li> 
 <li>支持可变参数 (VarArgs)</li> 
</ul>
<p>在 Tag 方法中，我们可以通过 <code>JetTagContext</code> 来获取相关内容。主要 API 如下：</p> 
<ul> 
 <li>String JetTagContext.getBodyContext()<br /> 获取 <code>#tag ... #end</code> 之间的内容</li> 
 <li>void JetTagContext.writeBodyContext()<br /> 将内容原封不动的在原地进行输出</li> 
 <li>void JetTagContext.getWriter().print(...)<br /> 自定义输出内容</li> 
 <li>JetContext JetTagContext.getContext()<br /> 获取模板管理的 <code>JetContext</code> 对象，在 Web 环境中，可以通过 <code>JetContext</code> 对象进一步获取 <code>request</code>, <code>response</code> 等对象。</li> 
 <li>JetEngine JetTagContext.getEngine()<br /> 获取模板全局 Engine。</li> 
</ul>
<p>详细了解 <code>JetTagContext</code> 具体 API，请看 apidocs。</p>
<p>关于模板的使用：</p> 
<ul> 
 <li>Tag 的参数必须和定义的一致。<br /> 如果定义为: <code>cache(JetTagContext ctx, String name, int timeout)</code>，那么在调用的时候，必须传2个参数，一个 String， 一个 int，比如： <code>#tag cache(&quot;abc&quot;, 123) ... #end</code></li> 
</ul>

<!-- markdown body end -->

    </div>
</div>

<div class="container">
    <div class="jb-footer">
        Copyright 2010-2014 Guoqiang Chen. All rights reserved.
        <br/>subchen&#64;gmail.com, QQ 交流圈：310491655
    </div>
</div>

<style type="text/css">
#cnzz_stat_icon_1000210720 {
	display: none;
}
</style>
<script type="text/javascript">
var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");
document.write(unescape("%3Cspan id='cnzz_stat_icon_1000210720'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "s22.cnzz.com/z_stat.php%3Fid%3D1000210720' type='text/javascript'%3E%3C/script%3E"));
</script>



</body>
</html>
